package com.koudai.finance.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.google.common.hash.Hashing;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.util.*;

/**
 * @Description: http工具类
 * @author: ls
 * @Date: 2020/7/10 15:52
 */
@Slf4j
public class HttpClientUtils {

    private static RequestConfig requestConfig;
    private static String charset = "utf-8";

    static {
        requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
    }

    /**
     * @Description: 创建HttpClients对象
     * @author: ls
     * @Date: 2020/7/10 15:57
     */
    public static CloseableHttpClient getHttpClient() {
        SSLContext sslContext = null;
        try {
            sslContext = SSLContexts.custom()
                    .loadTrustMaterial(null, (x509Certificates, s) -> true)
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return HttpClients
                .custom()
                .setSSLContext(sslContext)
                .setSSLHostnameVerifier(new NoopHostnameVerifier())
                .build();
    }

    /**
     * @Description: post请求-参数支持json字符串、map、JSONObject
     * @author: ls
     * @Date: 2020/7/10 15:57
     */
    public static JSONObject httpPost(String url, Object obj, Header[] headers) {
        JSONObject jsonObject = new JSONObject();
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeaders(headers);
        // 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);
        try {
            if (null != obj) {
                StringEntity entity;
                if (obj instanceof String) {
                    entity = new StringEntity(obj.toString(), charset);
                } else {
                    entity = new StringEntity(JSON.toJSONString(obj), charset);
                }
                entity.setContentEncoding(charset);
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            response = httpClient.execute(httpPost);
            jsonObject = buildResult(response);
        } catch (Exception e) {
            log.error("post请求提交失败:", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpPost.releaseConnection();
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }


    /**
     * @Description: post请求返回字符串-参数支持json字符串、map、JSONObject
     * @author: ls
     * @Date: 2020/7/10 15:57
     */
    public static String postReturnStr(String url, Object obj) {
        String result = "";
        StringBuilder requestText = new StringBuilder();
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = getHttpClient();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求和传输超时时间
        httpPost.setConfig(requestConfig);
        try {
            if (null != obj) {
                StringEntity entity;
                if (obj instanceof String) {
                    entity = new StringEntity(obj.toString(), charset);
                } else {
                    entity = new StringEntity(JSON.toJSONString(obj), charset);
                }
                entity.setContentEncoding(charset);
                entity.setContentType("application/json");
                httpPost.setEntity(entity);
            }
            response = httpClient.execute(httpPost);
            byte[] x = EntityUtils.toByteArray(response.getEntity());
            requestText.append(new String(x, StandardCharsets.UTF_8));
            result = requestText.toString();
        } catch (Exception e) {
            log.error("post请求提交失败:", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpPost.releaseConnection();
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * @Description: post请求传输String参数 例如：name=Jack&sex=1&type=2
     * Content-type:application/x-www-form-urlencoded
     * @author: ls
     * @Date: 2020/7/21 14:05
     */
    public static JSONObject httpPostForm(String url, Map<String, String> params, Header[] headers) {
        JSONObject jsonObject = new JSONObject();
        CloseableHttpClient httpClient = getHttpClient();
        CloseableHttpResponse response = null;
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfig);
        httpPost.setHeaders(headers);
        try {
            if (!CollectionUtils.isEmpty(params)) {
                List<NameValuePair> paramList = new ArrayList<>();
                Set<String> keySet = params.keySet();
                for (String key : keySet) {
                    paramList.add(new BasicNameValuePair(key, params.get(key)));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(paramList, charset));
            }
            response = httpClient.execute(httpPost);
            jsonObject = buildResult(response);
        } catch (IOException e) {
            log.error("post请求提交失败:", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpPost.releaseConnection();
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }

    /**
     * @Description: 发送get请求
     * @author: ls
     * @Date: 2020/7/10 16:00
     */
    public static JSONObject httpGet(String url, Header[] headers) {
        JSONObject jsonResult = null;
        CloseableHttpResponse response = null;
        CloseableHttpClient client = getHttpClient();
        HttpGet request = new HttpGet(url);
        request.setConfig(requestConfig);
        request.setHeaders(headers);
        try {
            response = client.execute(request);
            jsonResult = buildResult(response);
        } catch (Exception e) {
            log.error("get请求提交失败:" + url, e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                request.releaseConnection();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonResult;
    }

    /**
     * @Description: 发送get请求
     * @author: ls
     * @Date: 2020/7/10 16:00
     */
    public static String httpGetString(String url, Header[] headers) {
        String result = null;
        CloseableHttpResponse response = null;
        CloseableHttpClient client = getHttpClient();
        HttpGet request = new HttpGet(url);
        request.setConfig(requestConfig);
        request.setHeaders(headers);
        try {
            response = client.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                try {
                    result = EntityUtils.toString(entity, "utf-8");
                } catch (IOException e) {
                    log.error("解析结果错误:", e);
                }
            }
        } catch (Exception e) {
            log.error("get请求提交失败:" + url, e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                request.releaseConnection();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * @Description: 处理请求结果
     * @author: ls
     * @Date: 2020/7/10 16:00
     */
    private static JSONObject buildResult(CloseableHttpResponse response) {
        JSONObject jsonObject = new JSONObject();
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            HttpEntity entity = response.getEntity();
            String strResult = null;
            try {
                strResult = EntityUtils.toString(entity, "utf-8");
            } catch (IOException e) {
                log.error("解析结果错误:", e);
            }
            jsonObject = JSONObject.parseObject(strResult);
        } else {
            log.error("请求异常{} ", response);
        }
        return jsonObject;
    }

    public static void main(String[] args) throws Exception {
        String url = "https://tsanghi.com/api/fin/stock/XSHG/weekly?token=c896a019dfb64812bbe77bbc4ebed42c&ticker=601857";
        JSONObject result = HttpClientUtils.httpGet(url,  null);
        System.out.println(result);
    }

}

